PS出的RSS总和大于实际物理内存

        使用ps aux 查看系统进程时,第六列即 RSS列显示的就是进程使用的物理内存。

        可是把系统所有进程的该列相加时,得到的总和又远远高于系统实际的物理内存?这到底是怎么回事呢?

        看一看linux是如何管理内存的就会知道。

        理解的意思是这样的,linux会在每个进程生成时分配一定量的内存给这个进程,这个只是分配,而体现在ps出来的是VSZ那列,这叫做虚拟内存。但实际上这些进程并没有占用这些内存。不妨,我也借用网上的一个例子来形容一下,就像银行发工资给员工一样,每个员工都有一个自己的银行卡,每月银行都会把固定的钱数打到员工的银行卡里,但是这个过程并不是把实际的钱发到员工手里,只是一串数字而已。实际上,银行并没有那么多钱的。回头再来看看linux给进程分配内存是不是和上面的举的例子很像呢?

        讲了上面的观点后,依然不能把笔者所设的问题解答,那么继续往下探讨:

        把系统所有进程的该列相加时,得到的总和又远远高于系统实际的物理内存?这是因为 ps 的结果,RSS 那部分,是包括共享内存的。这里使用 pmap 来看看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
pmap -d 24030
24030: /usr/local/php/bin/php-cgi --fpm --fpm-config /usr/local/php/etc/php-fpm.conf
Address Kbytes Mode Offset Device Mapping
0000000000400000 6444 r-x-- 0000000000000000 008:00002 php-cgi
0000000000c4b000 272 rw--- 000000000064b000 008:00002 php-cgi
0000000000c8f000 52 rw--- 0000000000c8f000 000:00000 [ anon ]
00000000059dc000 9572 rw--- 00000000059dc000 000:00000 [ anon ]
0000003519000000 508 r-x-- 0000000000000000 008:00002 libfreetype.so.6.3.10
000000351907f000 2048 ----- 000000000007f000 008:00002 libfreetype.so.6.3.10
中间部分省略
00002b757df75000 4 rw--- 000000000000a000 008:00002 libnss_files-2.5.so
00002b757df76000 32768 rw-s- 0000000000000000 000:00008 zero (deleted)
00002b7580685000 4 rw-s- 0000000000000000 000:00008 zero (deleted)
00007fff2e126000 476 rwx-- 00007fff2e126000 000:00000 [ stack ]
00007fff2e19d000 8 rw--- 00007fff2e19d000 000:00000 [ anon ]
ffffffffff600000 8192 ----- 0000000000000000 000:00000 [ anon ]
mapped: 139548K writeable/private: 12344K shared: 32772K

        pmap是用来显示内存使用的指令,-d 后面跟的是进程id. 关于pmap的使用以及显示的数据请看http://www.lishiming.net/thread-977-1-1.html

        linux 会把一些shared libraries 载入到内存中,在pmap 的输出中,这些shared libraries 的名字通常是 lib*.so ,如 libX11.so.6.2.0 。

        这个 libX11.so.6.2.0 会被很多process load 到自己的运行环境中,同时,ps 输出的RSS 结果中,每个process 都包含了这个libX11.so.6.2.0 ,而事实上它只被load 了一次,如果单纯把ps 的结果相加,这样就重复计算了。

        看pmap输出的结果,其实php-cgi 单纯进程所占的内存是这个writeable/private: 12344K